package com.ecoolex.chinadutyfree.retailer.admin.graphql;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.ecoolex.chinadutyfree.retailer.admin.core.AdminConstant;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsBrand;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsBrand.Column;
import com.ecoolex.chinadutyfree.retailer.pojo.AddGoodsBrandDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.EditGoodsBrandDTO;
import com.ecoolex.chinadutyfree.retailer.ws.GoodsService;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.google.common.collect.Lists;


@GraphQL2Module(type = Type.Admin, description = "商品品牌管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY, key = GoodsBrandGraphql.AUTH, name = "商品品牌管理")
public class GoodsBrandGraphql {

	public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-GOODS-BRAND";

	@Reference
	private GoodsService goodsService;

	@Autowired
	private StorageService storageService;

	@TypeField(type = GoodsBrand.class, field = "logo", description = "logo")
	public StorageInfo logo(@Source GoodsBrand source) {
		return storageService.get(source.getLogo());
	}

	@TypeField(type = GoodsBrand.class, field = "image", description = "图片")
	public StorageInfo image(@Source GoodsBrand source) {
		return storageService.get(source.getImage());
	}
	
	private static final String AUTH_GET = AUTH + "-GET";

	@QueryField(field = "goodsBrand", description = "获取商品品牌详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "获取商品品牌详情")
	public GoodsBrand get(Integer brandId, AdminMemberAuthority user) {
		user.assertLogin();
		return goodsService.getBrandById(brandId);
	}

	private static final String AUTH_QUERY = AUTH + "-QUERY";

	@QueryField(field = "goodsBrandList", description = "查询商品品牌列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询商品品牌列表")
	public Pagination<GoodsBrand> query(String name, Integer categoryId, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
		user.assertLogin();
		return goodsService.queryBrand(name, categoryId, sorts, page);
	}

	@MutationField(field = "uploadGoodsBrandLogo", description = { "上传商品品牌Logo" })
	public StorageInfo uploadGoodsBrandLogo(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("GoodsBrand", "Logo");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(2));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}

	@MutationField(field = "uploadGoodsBrandImage", description = { "上传商品品牌图片" })
	public StorageInfo uploadGoodsBrandImage(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("GoodsBrand", "Image");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(2));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}

	private static final String AUTH_ADD = AUTH + "-ADD";

	@MutationField(field = "addGoodsBrand", description = "添加商品品牌")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加商品品牌")
	public GoodsBrand add(@NonNull AddGoodsBrandDTO add, AdminMemberAuthority user) {
		user.assertAuth(AUTH_ADD);
		return goodsService.addBrand(add, user.userName());
	}

	private static final String AUTH_EDIT = AUTH + "-EDIT";

	@MutationField(field = "editGoodsBrand", description = "编辑商品品牌")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑商品品牌")
	public GoodsBrand edit(@NonNull EditGoodsBrandDTO edit, AdminMemberAuthority user) {
		user.assertAuth(AUTH_EDIT);
		GoodsBrand old = goodsService.getBrandById(edit.getBrandId());
		Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "商品品牌不存在");
		BeanUtil.copy(edit,
			old,
			Lists.newArrayList(Column.deleted, Column.createUser, Column.createTime).stream().map(
				Column::getJavaProperty).toArray(String[]::new));

		return goodsService.updateBrand(edit, user.userName());
	}

	private static final String AUTH_DEL = AUTH + "-DEL";

	@MutationField(field = "delGoodsBrand", description = "删除商品品牌")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除商品品牌")
	public Boolean del(@NonNull Integer brandId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_DEL);
		GoodsBrand record = goodsService.getBrandById(brandId);
		Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "商品品牌不存在");
		goodsService.deleteBrand(record, user.userName());
		return true;
	}
}

